# -*- coding: utf-8 -*-
import web
import json
import logging
import threading
import subprocess
import sys
import signal
import os
import time

import requests
import serial
import re

urls = ("/startcp", "startcheck",
        "/stopcp", "stopcheck",
        "/wifiprobe", "wifiprobe",
        "/lastgps", "gpsnow")
app = web.application(urls, globals())

g_runPidMap = {}

g_webGpsUrl = 'http://120.79.144.241:9090/CityInspectors/sendGps.json'
g_webWifiUrl = 'http://120.79.144.241:9090/CityInspectors/sendWifiProbe.json'

macId = 'DL001'
web.g_lastGPSData = {}

web.g_probeData = {}

# web.macId = macId


wifi_P = -50
wifi_N = 3


class startcheck:
    def GET(self):
        msgline = 'top'
        start_thread = threading.Thread(target=self.startCpExec, name="startCpThread", args=(msgline, 'tttt',))
        # start_thread.setDaemon(True)
        start_thread.start()
        return 'Hello, world!'

    def POST(self):
        reuqestData = web.data()
        jsondata = json.loads(reuqestData)
        print(jsondata)
        ip = jsondata['ip']
        userName = jsondata['userName']
        passwd = jsondata['passwd']
        cid = jsondata['cid']

        msgline = './plate '+ip+' '+userName+' '+passwd+' '+cid
        logging.error(msgline)
        start_thread = threading.Thread(target=self.startCpExec, name="startCpThread", args=(msgline, cid,))
        # start_thread.setDaemon(True)
        start_thread.start()
        resp = {}
        resp['code'] = '1'

        return json.dumps(resp)

    def startCpExec(self, func, cid):
        res = subprocess.Popen(func, stdin=subprocess.PIPE,stdout=subprocess.PIPE, shell=True, preexec_fn=os.setpgrp)

        global g_runPidMap
        g_runPidMap[cid] = res
        logging.error('推流执行进程 pid:'+str(res.pid))


class stopcheck:
    def GET(self):
        if g_runPidMap.has_key('tttt'):
            try:
                proc = g_runPidMap['tttt']
                proc.terminate()
                proc.wait()
                os.killpg(proc.pid, signal.SIGTERM)
            except Exception as e:
                logging.error(e)
        return 'Hello, world!'

    def POST(self):
        reuqestData = web.data()
        jsondata = json.loads(reuqestData)
        print(jsondata)
        cid = jsondata['cid']
        resp = stopCP()
        return json.dumps(resp)
def stopCP():
    resp = {}
    resp['code'] = '1'

    if g_runPidMap.has_key(cid):
        try:
            resp['code'] = '1'
            proc = g_runPidMap[cid]
            proc.terminate()
            proc.wait()
            os.killpg(proc.pid, signal.SIGTERM)

        except Exception as e:
            logging.error(e)

    else:
        resp['code'] = '0'

    return resp



class wifiprobe:
    def GET(self):
        if g_runPidMap.has_key('tttt'):
            try:
                proc = g_runPidMap['tttt']
                proc.terminate()
                proc.wait()
                os.killpg(proc.pid, signal.SIGTERM)
            except Exception as e:
                logging.error(e)
        return 'Hello, world!'

    def POST(self):

        data = web.input()
        # global g_probeData
        web.g_probeData = json.loads(data['data'])
        # print(json.loads(sendData))
        print(web.g_lastGPSData)
        try:
            if web.g_lastGPSData.has_key('lat'):
                web.g_probeData['lat'] = web.g_lastGPSData['lat']
                web.g_probeData['lon'] = web.g_lastGPSData['lon']
            
            # web.g_probeData['macId'] = macId
            print("before recv data")
            # print(g_probeData[macId])
        except Exception, e:
            logging.error(e)
        return 'post'

def probeThreadStart(strs):
    indexflag = 0

    while True:
        indexflag = indexflag+1
        # global g_probeData
        if indexflag % 6 == 0:
            
            try:
                # print("before send post to web")
                
                senddata = web.g_probeData
                senddata['macId'] = macId

                # print(senddata)
                # sendd = {}
                # sendd['id']="00740166"
                # sendd['data']=[]
                # sendd['mmac']="10:a4:be:74:01:66"
                # sendd['rate']="5"
                # sendd['time']="Thu Jul 26 11:03:51 2018"
                # sendd['lat']=""
                # sendd['lon']=""

                inhttpRes = requests.post(g_webWifiUrl, json=senddata)
                # print(inhttpRes)
                # print('发送WIFI探针请求后返回值:'+str(inhttpRes.text))
                logging.warn('发送WIFI探针请求后返回值:'+str(inhttpRes.text))
            except Exception, e:
                logging.error(e)
                logging.error('发送WIFI探针请求出错')
            indexflag = 0

        time.sleep(1)


class gpsnow:
    def GET(self):
        return json.dumps(web.g_lastGPSData)

    def POST(self):
        return json.dumps(web.g_lastGPSData)


class GpsParser:
    def __init__(self, port='/dev/ttyACM0', baudrate=9600, timeout=1):
        self.port = port
        self.baud = baudrate
        self.timeout = timeout
        self.GpsUart = serial.Serial(port, baudrate, timeout=timeout)
        self.GpsUart.flush()
        self.read()

    def messageType(self, message):
        checksum = self.checkDataSum(message)
        if checksum is False:
            return None
        if re.match(r'\$GPGGA', message):
            return 'GPGGA'
        elif re.match(r'\$GPRMC', message):
            return 'GPRMC'
        elif re.match(r'\$GNGGA', message):
            return 'GNGGA'

        return None

    def checkDataSum(self, message):
        payload = re.split(r'\*', message)

    def parseGPGGA(self, message):
        parsed_input = message.split(',')
        self.time = parsed_input[1]  # UTC time
        self.lat = parsed_input[2]
        self.lat_ns = parsed_input[3]
        self.lon = parsed_input[4]
        self.lon_ew = parsed_input[5]
        self.fix = parsed_input[6]
        self.sats = parsed_input[7]
        self.altitude = parsed_input[9]
        return self.current_values()
    def parseGNGGA(self, message):
        parsed_input = message.split(',')
        self.time = parsed_input[1]  # UTC time
        self.lat = parsed_input[2]
        self.lat_ns = parsed_input[3]
        self.lon = parsed_input[4]
        self.lon_ew = parsed_input[5]
        self.fix = parsed_input[6]
        self.sats = parsed_input[7]
        self.altitude = parsed_input[9]
        return self.current_values()

    def parseGPRMC(self, message):
        parsed_input = message.split(',')
        self.time = parsed_input[1]  # UTC time
        self.lat = parsed_input[3]
        self.lon = parsed_input[5]
        return self.current_values()

    def read(self):
        # '''
        # text = "$GPGGA,184353.07,1929.045,S,02410.506,E,1,04,2.6,100.00,M,-33.9,M,,0000*6D"
        # rawType = self.messageType(text)
        # if rawType is None:
        #     pass
        # elif rawType == 'GPGGA':
        #     return self.parseGPGGA(text)
        # elif rawType == 'GPRMC':
        #     return self.parseGPRMC(text)
        # '''

        while True:
            raw = self.GpsUart.readline()
            # print raw
            rawType = self.messageType(raw)

            if rawType is None:
                pass
            elif rawType == 'GPGGA':
                return self.parseGPGGA(raw)
            elif rawType == 'GNGGA':
                return self.parseGNGGA(raw)
            # elif rawType == 'GPRMC':
            #  	return self.parseGPRMC(raw)

    def current_values(self):
        data = {}
        data['time'] = self.time
        data['lat'] = self.lat
        data['lat_ns'] = self.lat_ns
        data['lon'] = self.lon
        data['lon_ew'] = self.lon_ew
        data['fix'] = self.fix
        data['sats'] = self.sats
        data['altitude'] = self.altitude

        return data


def gpsThreadStart(str):
    launchGps = GpsParser()
    indexflag = 0
    while True:

        indexflag = indexflag+1

        sendData = launchGps.read()
        print(sendData)
        
        web.g_lastGPSData = sendData
        if indexflag % 6 == 0:
            sendData['checkId'] = macId
            try:
                # data = json.dumps(sendData)
                inhttpRes = requests.post(g_webGpsUrl, json=sendData)
                print(inhttpRes)
                logging.info('发送GPS请求后返回值:'+str(inhttpRes.text))
            except Exception, e:
                logging.info(e)
                logging.info('发送GPS请求出错')
            print(sendData)
            indexflag = 0

        time.sleep(1)


class WifiParser:
    def __init__(self, port='/dev/ttyUSB0', baudrate=115200, timeout=1):
        self.port = port
        self.baud = baudrate
        self.timeout = timeout
        self.WifiUart = serial.Serial(port, baudrate, timeout=timeout)
        self.WifiUart.flush()
        self.read()

    def checkDataSum(self, message):
        payload = re.split(r'\*', message)

    def getBrand(mac):
        mac_array = mac.split(':')
        top3mac = mac_array[1] + ":" + mac_array[2] + ":" + mac_array[3]
        return top3mac

    def getDistance(self, signal):
        up = wifi_P - int(signal)
        down = 10 * wifi_N
        index = up / down
        res = 10 ** index
        #print("估算距离为%d米", res)
        return str(res)

    def parseWifiParam(self, message):
        print( "parseWifiParam: " + message)
        row = message.strip()
        parsed_input = row.split('|')
        length = len(parsed_input)
        if length == 6:
            print("length == 6")
            self.mac = parsed_input[0]  # Frame 源 MAC
            self.router = parsed_input[1]  # Frame 目的 MAC
            #self.unknown1 = parsed_input[2]  # Frame 大类
            #self.unknown2 = parsed_input[3]  # Frame 小类
            self.channel = parsed_input[4]  # 信道
            self.signal = parsed_input[5]  # RSSI 信号强度
            self.distance = self.getDistance(parsed_input[5])
            self.brand = ""  # getBrand(parsed_input[0])
            self.gps = web.g_lastGPSData
        else:
            print("length not == 6")
            self.mac = ""  # Frame 源 MAC
            self.router = ""  # Frame 目的 MAC
            #self.unknown1 = ""  # Frame 大类
            #self.unknown2 = ""  # Frame 小类
            self.channel = ""  # 信道
            self.signal = ""  # RSSI 信号强度
            self.distance = ""
            self.brand = ""  # getBrand(parsed_input[0])
            self.gps = web.g_lastGPSData


        return self.current_values()

    def read(self):
        while True:
            raw = self.WifiUart.readline()
            return self.parseWifiParam(raw)

    def current_values(self):
        data = {}
        data['mac'] = self.mac
        data['router'] = self.router
        #data['unknown1'] = self.unknown2
        #data['unknown2'] = self.unknown2
        data['channel'] = self.channel
        data['signal'] = self.signal
        data['distance'] = self.distance
        data['brand'] = self.brand
        data['gps'] = self.gps

        return data


# def wifiThreadStart(strs):
#     launchWifi = WifiParser()

#     indexflag = 0
#     while True:

#         indexflag = indexflag+1

#         sendData = launchWifi.read()
#         if indexflag % 6 == 0:
#             sendData['macid'] = macId
#             try:
#             	print("wifi send: ")
#                 print(sendData)
#                 inhttpRes = requests.post(g_webWifiUrl, json=sendData)
#                 logging.error('发送Wifi探针请求后返回值:'+str(inhttpRes.text))
#             except Exception, e:
#                 logging.error(e)
#                 logging.error('发送Wifi探针请求出错')
#             print(sendData)
#             indexflag = 0

#         time.sleep(1)


if __name__ == "__main__":
    gpsThread = threading.Thread(target=gpsThreadStart, name="gpsThreadStart",args = ('',))
    gpsThread.start()

    
    #probeThread = threading.Thread(target=probeThreadStart, name="probeThreadStart", args=('',))
    # probeThread.setDaemon(True)
    #probeThread.start()

    #wifiThread = threading.Thread(
    #    target=wifiThreadStart, name="wifiThreadStart", args=('',))
    #wifiThread.start()
    app.run()
